package cmpe.swe.purcom.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cmpe.swe.purcom.dao.CommunityDao;
import cmpe.swe.purcom.model.Community;
import cmpe.swe.purcom.model.Event;
import cmpe.swe.purcom.model.EventAttendance;
import cmpe.swe.purcom.model.FeedItem;
import cmpe.swe.purcom.model.Service;
import cmpe.swe.purcom.model.ServiceContribution;
import cmpe.swe.purcom.model.Stuff;
import cmpe.swe.purcom.model.StuffContribution;
import cmpe.swe.purcom.model.User;

@Component
public class CommunityService {
	@Autowired
	private CommunityDao communityDao;

	public CommunityDao getCommunityDao() {
		return communityDao;
	}

	public void setCommunityDao(CommunityDao communityDao) {
		this.communityDao = communityDao;
	}

	/**
	 * Returns a new created Community object by the user with given userId
	 * 
	 * @param c
	 *            a Community Object
	 * @param userId
	 *            a variable which is used for user identification
	 * @return a Community Object
	 */
	public Community createCommunity(Community c, Long userId) {
		Community cCreated = communityDao.createCommunity(c);
		communityDao.linkCommunityWithUser(cCreated.getId(), userId, "CREATOR");
		return cCreated;
	}

	public List<Community> getCommunities() {
		return communityDao.getCommunities();
	}

	/**
	 * Gets the list of communities with which user whose id is given is
	 * associated as creator or member
	 * 
	 * @param userId
	 *            id of user
	 * @return the list of associated communities with the user
	 */
	public List<Community> getMyCommunities(Long userId) {
		return communityDao.getMyCommunities(userId);
	}

	public Community getCommunity(Long id) {
		return communityDao.getCommunity(id);
	}

	public List<Community> searchCommunitiesByName(String name) {
		return communityDao.getCommunitiesByName(name);
	}

	/**
	 * Makes linkage between a user and a community, then returns the
	 * communityID
	 * 
	 * @param communityID
	 *            a variable which is used for community identification
	 * @param userID
	 *            a variable which is used for user identification
	 * @return CommunityID
	 */
	public Community joinCommunity(Long communityID, Long userID) {
		communityDao.linkCommunityWithUser(communityID, userID, "MEMBER");
		return communityDao.getCommunity(communityID);
	}

	public List<User> getCommunityMembers(Long id) {
		return communityDao.getCommunityMembers(id);
	}

	public Map<String, Object> getMembership(Long communityId, Long userId) {
		return communityDao.getMembership(communityId, userId);
	}

	public void leaveCommunity(Long communityId, Long userId) {
		communityDao.leaveCommunity(communityId, userId);
	}
	/*
	 * STUFF methods
	 */

	/**
	 * Returns a new created Stuff object by the user with given userId
	 * 
	 * @param s
	 *            a Stuff object
	 * @param userId
	 *            a variable which is used for user identification
	 * @return a Stuff object
	 */
	public Stuff createStuff(Stuff s, Long userId) {
		Stuff sCreated = communityDao.createStuff(s);
		communityDao.linkStuffWithUser(sCreated.getId(), userId, "SUPERVISOR");
		return sCreated;
	}

	public List<Stuff> getStuffs(Long communityId) {
		return communityDao.getStuffs(communityId);
	}

	public Stuff getStuff(Long communityId, Long stuffId) {
		return communityDao.getStuff(communityId, stuffId);
	}

	public StuffContribution contributeToStuff(StuffContribution sc) {
		return communityDao.contributeToStuff(sc);
	}

	/*
	 * SERVICE methods
	 */

	/**
	 * Returns a new created Service object by the user with given userId
	 * 
	 * @param s
	 *            a Service object
	 * @param userId
	 *            a variable which is used for user identification
	 * @return a Service object
	 */
	public Service createService(Service s, Long userId) {
		Service sCreated = communityDao.createService(s);
		communityDao
				.linkServiceWithUser(sCreated.getId(), userId, "SUPERVISOR");
		return sCreated;
	}

	public List<Service> getServices(Long communityId) {
		return communityDao.getServices(communityId);
	}

	public Service getService(Long communityId, Long serviceId) {
		return communityDao.getService(communityId, serviceId);
	}

	public ServiceContribution contributeToService(ServiceContribution sc) {
		return communityDao.contributeToService(sc);
	}

	/*
	 * EVENT methods
	 */

	/**
	 * Returns a new created Event object by the user with given userId
	 * 
	 * @param e
	 *            an Event object
	 * @param userId
	 *            a variable which is used for user identification
	 * @return an Event object
	 */
	public Event createEvent(Event e, Long userId) {
		Event eCreated = communityDao.createEvent(e);
		communityDao.linkEventWithUser(eCreated.getId(), userId, "MODERATOR");
		return eCreated;
	}

	public List<Event> getEvents(Long communityId) {
		return communityDao.getEvents(communityId);
	}

	public Event getEvent(Long communityId, Long eventId) {
		return communityDao.getEvent(communityId, eventId);
	}

	/**
	 * Make linkage between user and event, and between event and community then
	 * returns the event
	 * 
	 * @param communityId
	 *            a variable which is used for community identification
	 * @param eventId
	 *            a variable which is used for event identification
	 * @param userId
	 *            a variable which is used for user identification
	 * @return
	 */
	public Event attendEvent(Long communityId, Long eventId, Long userId) {
		communityDao.linkEventWithUser(eventId, userId, "ATTENDEE");
		return communityDao.getEvent(communityId, eventId);
	}

	/*
	 * FEEDS methods
	 */

	/**
	 * Returns the contributions within stuff whose id is given
	 * 
	 * @param stuffId
	 *            id of stuff
	 * @return List of stuff contributions
	 */
	public List<StuffContribution> getActivityFeedOfStuff(Long stuffId) {
		return communityDao.getActivityFeedOfStuff(stuffId);
	}

	/**
	 * Returns the contributions within service whose id is given
	 * 
	 * @param serviceId
	 *            id of service
	 * @return List of service contributions
	 */
	public List<ServiceContribution> getActivityFeedOfService(Long serviceId) {
		return communityDao.getActivityFeedOfService(serviceId);
	}

	/**
	 * Returns the attendances within event whose id is given
	 * 
	 * @param eventId
	 *            id of event
	 * @return List of event attendances
	 */
	public List<EventAttendance> getActivityFeedOfEvent(Long eventId) {
		return communityDao.getActivityFeedOfEvent(eventId);
	}

	/**
	 * Returns the contributions/attendances of the community whose id is given
	 * 
	 * @param communityId
	 *            id of community
	 * @return List of feed items
	 */
	public List<FeedItem> getActivityFeedOfCommunity(Long communityId) {
		return communityDao.getActivityFeedOfCommunity(communityId);
	}
	
	/**
	 * Returns the contributions/attendances of communities with which somehow
	 * user whose id is given is associated
	 * 
	 * @param userId
	 *            id of user
	 * @return List of feed items
	 */
	public List<FeedItem> getActivityFeedOfMyCommunities(Long userId) {
		return communityDao.getActivityFeedOfMyCommunities(userId);
	}
}
